﻿using Library.API.Entities;
using Library.API.Helpers;
using Library.API.Models;
using Library.API.Repositories.Interfaces;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Linq.Dynamic.Core;
using Library.API.Extensions;

namespace Library.API.Repositories
{
    public class AuthorRepository : RepositoryBase<Author, Guid>, IAuthorRepository
    {
        private Dictionary<string, PropertyMapping> mappingDict = null;

        public AuthorRepository(DbContext dbContext) : base(dbContext)
        {
            this.mappingDict = new Dictionary<string, PropertyMapping>(StringComparer.OrdinalIgnoreCase);
            this.mappingDict.Add("Name", new PropertyMapping("Name"));
            this.mappingDict.Add("Age", new PropertyMapping("BirthDate", true));
            this.mappingDict.Add("BirthPlace", new PropertyMapping("BirthPlace"));
        }

        public Task<PagedList<Author>> GetAllAsync(AuthorResourceParameters parameters)
        {
            IQueryable<Author> queryableAuthors = DbContext.Set<Author>();
            if (!string.IsNullOrWhiteSpace(parameters.BirthPlace))
            {
                queryableAuthors = queryableAuthors.Where(m => m.BirthPlace.ToLower() == parameters.BirthPlace);
            }

            if (!string.IsNullOrWhiteSpace(parameters.SearchQuery))
            {
                queryableAuthors = queryableAuthors.Where(m =>
                    m.BirthPlace.ToLower().Contains(parameters.SearchQuery.ToLower()) ||
                    m.Name.ToLower().Contains(parameters.SearchQuery.ToLower()));
            }

            var orderedAuthors = queryableAuthors.Sort(parameters.SortBy, this.mappingDict);
            return PagedList<Author>.CreateAsync(orderedAuthors, parameters.PageNumber, parameters.PageSize);
        }

        public async Task<Author> GetAuthorAsync(Guid authorId)
        {
            return await DbContext.Set<Author>()
                .SingleOrDefaultAsync(author => author.Id == authorId);
        }
    }
}
